home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir41 / tsrsrc35.zip / FMARK.ASM < prev    next >
Assembly Source File  |  1993-10-18  |  18KB  |  479 lines

  1. ;==============================================================================
  2. ;FMARK.ASM - mark a position in memory,
  3. ;            above which TSRs will later be cleared by RELEASE
  4. ;            this version leaves a minimal size MARK in memory,
  5. ;              storing the rest on disk
  6. ;            requires a single command line parameter naming
  7. ;              the file where the mark will be stored
  8. ;
  9. ; Syntax:  FMARK [/Q] [d:][path]filename
  10. ;==============================================================================
  11. ; written for TASM
  12. ; by Kim Kokkonen, TurboPower Software
  13. ; Copyright (c) 1986,1993 Kim Kokkonen, TurboPower Software.
  14. ; May be freely distributed but not sold except by permission.
  15. ; telephone: 719-260-6641, Compuserve 76004,2611
  16. ;==============================================================================
  17. ; version 2.0  6/17/86
  18. ;   start at a version number compatible with other TSR utilities
  19. ; :
  20. ; long intervening history
  21. ; :
  22. ; version 3.0  9/24/91
  23. ;   add Quiet option
  24. ; version 3.1  11/4/91
  25. ;   no change
  26. ; version 3.2  11/22/91
  27. ;   change method of accessing high memory
  28. ;   store parent len as well as parent segment
  29. ; version 3.3  1/8/92
  30. ;   detect full disk while writing mark file
  31. ;   erase partial mark file if any error occurs during execution
  32. ; version 3.4  2/14/92
  33. ;   no change
  34. ; version 3.5 10/18/93
  35. ;   new hybrid method for finding high memory
  36. ;==============================================================================
  37. ;
  38. Cseg    segment public para
  39.         assume  cs:Cseg, ds:Cseg, es:Cseg
  40.         locals  @@
  41.  
  42.         org     016H               ;access to parent's PSP
  43. parpsp  label   word
  44.  
  45.         org     02CH
  46. envseg  label   word               ;access to environment segment
  47.  
  48.         org     80H
  49. cmdlen  label   byte               ;command line length
  50.         org     81H
  51. cmdlin  label   byte               ;first character of command line
  52.  
  53.         org     100H
  54.  
  55. fmark   proc    near
  56.  
  57. ;deallocate environment block of this mark
  58.         push    es
  59.         mov     ax,envseg       ;environment segment
  60.         mov     es,ax           ;  into es
  61.         mov     ah,49H
  62.         int     21H             ;deallocate, no reason for an error to occur
  63.         pop     es
  64.  
  65. ;find first mcb in high memory, if any
  66.         mov     ax,5802h
  67.         int     21H                     ;get umb link status
  68.         or      al,al                   ;high memory already linked?
  69.         jz      @@u1                    ;jump if not
  70.  
  71.         call    findhidos               ;find mcb using linked chain
  72.  
  73.         or      ax,ax                   ;valid mcb seg returned?
  74.         jz      @@u9                    ;jump if not
  75.         mov     cx,ax
  76.         jmp     @@9                     ;found first umb
  77.  
  78. @@u1:   mov     ax,5803H
  79.         mov     bx,1
  80.         int     21H                     ;link umb
  81.         jc      @@u9                    ;jump if failed
  82.  
  83.         call    findhidos               ;find mcb using linked chain
  84.  
  85.         push    ax                      ;save result
  86.         mov     ax,5803H
  87.         xor     bx,bx
  88.         int     21H                     ;unlink umb
  89.         pop     ax                      ;restore result
  90.  
  91.         or      ax,ax                   ;valid mcb seg returned?
  92.         jz      @@u9                    ;jump if not
  93.         mov     cx,ax
  94.         jmp     @@9                     ;found first umb
  95.  
  96. @@u9:   mov     ax,3000h                ;get DOS version
  97.         int     21H
  98.         cmp     al,3
  99.         jb      @@7                     ;no XMS driver possible
  100.         mov     ax,4300h
  101.         int     2Fh                     ;multiplex call for XMS
  102.         cmp     al,80h                  ;proper signature?
  103.         jne     @@7                     ;no XMS driver
  104.         mov     ax,4310h                ;get XMS control address
  105.         int     2Fh
  106.         mov     xmsxxx,bx               ;save it
  107.         mov     xmsxxx[2],es
  108.         mov     ah,10h
  109.         mov     dx,0FFFFh
  110.         call    dword ptr xmsadr        ;ask to allocate FFFF paras of UMB
  111.         cmp     bl,0B0h                 ;will fail with B0 if UMBs avail
  112.         je      @@0
  113.         cmp     bl,0B1h                 ;will fail with B1 if UMBs all allocated
  114.         jne     @@7                     ;no UMBs exist
  115. @@0:    int     12H
  116.         mov     cl,6
  117.         shl     ax,cl                   ;get segment of top of memory
  118.  
  119. @@1:    mov     es,ax
  120.         cmp     byte ptr es:[0000h],'M' ;potential mcb?
  121.         jnz     @@6                     ;not an mcb, try next segment
  122. @@2:    mov     cx,ax                   ;save potential start mcb in cx
  123. @@3:    inc     ax
  124.         add     ax,es:[0003h]           ;ax = start of next mcb
  125.         jc      @@5                     ;can't be an mcb if we wrapped
  126.         mov     es,ax                   ;address of next mcb
  127.         mov     dl,es:[0000h]
  128.         cmp     dl,'M'
  129.         jz      @@3                     ;good start mcb
  130.         cmp     dl,'Z'
  131.         jz      @@9                     ;good end mcb
  132. @@5:    mov     ax,cx                   ;restore last start segment
  133. @@6:    cmp     ax,0FFFFh               ;top of memory?
  134.         je      @@7
  135.         inc     ax                      ;try next segment
  136.         jmp     @@1
  137.  
  138. @@7:    xor     cx,cx                   ;no matching UMB
  139. @@9:    mov     firsthimcb,cx           ;store first high mcb
  140.  
  141. ;parse command line for file name
  142.         push    cs
  143.         pop     es
  144.         mov     si,offset cmdlin ;point to command line
  145.         mov     di,offset filnm  ;point to filename storage string
  146.         cld
  147.  
  148. get1:   lodsb                    ;get first non-blank
  149.         cmp     al,32            ;skip space
  150.         je      get1
  151.         cmp     al,9             ;skip tab
  152.         je      get1
  153.         cmp     al,13            ;check for end of input
  154.         jne     geto             ;got a non-blank, now get the parameter
  155.         cmp     di,offset filnm  ;filename already specified?
  156.         jne     gotit            ;done if so
  157.         jmp     error            ;no parameter --> error
  158.  
  159. geto:   cmp     al,'/'           ;check for option
  160.         je      getoc
  161.         cmp     al,'-'
  162.         jne     get2
  163. getoc:  lodsb
  164.         call    upcase
  165.         cmp     al,'Q'
  166.         jnz     operr
  167.         mov     quiet,1          ;set quiet option
  168.         jmp     get1             ;loop around
  169.  
  170. operr:  mov     dx,offset badopt ;bad option
  171.         jmp     errmsg
  172.  
  173. get2:   cmp     di,offset filnm  ;filename already specified?
  174.         jne     operr            ;error if so
  175.  
  176. get2a:  call    upcase           ;upcase char in al
  177.         stosb                    ;store the non-blank character
  178.         lodsb                    ;get next character
  179.         cmp     al,32
  180.         je      get1             ;loop back around for blank
  181.         cmp     al,9
  182.         je      get1             ;loop back around for tab
  183.         cmp     al,13
  184.         je      gotit            ;terminate for <cr>
  185.         jmp     short get2a      ;keep adding characters to filename
  186.  
  187. ;create the specified file
  188. gotit:  mov     al,0
  189.         stosb                    ;terminate ASCIIZ pathname
  190.         mov     dx,offset filnm
  191.         xor     cx,cx            ;normal attribute
  192.         mov     ah,3CH
  193.         int     21H              ;DOS CREAT
  194.         jae     store
  195.  
  196.         mov     dx,offset badfil ;bad file name
  197.         jmp     errmsg
  198.  
  199. ;store the interrupt vector table
  200. store:  mov     bx,ax           ;keep file handle in bx
  201.         push    ds              ;save ds
  202.         mov     cx,400H         ;1024 bytes to store
  203.         xor     ax,ax
  204.         mov     ds,ax           ;segment 0
  205.         assume  ds:nothing
  206.         mov     dx,ax           ;offset 0
  207.         call    blockwrite      ;write interrupts to file
  208.         assume  ds:cseg
  209.  
  210. ;store the EGA save pointer
  211. egasav: push    ds              ;save ds
  212.         mov     cx,0008H        ;8 bytes to store
  213.         mov     ax,0040H
  214.         mov     ds,ax           ;BIOS data segment
  215.         assume  ds:nothing
  216.         mov     dx,00A8H        ;EGA save table pointer
  217.         call    blockwrite      ;write save pointers to file
  218.         assume  ds:cseg
  219.  
  220. ;store the interapplications communications area
  221. intcom: push    ds              ;save ds
  222.         mov     cx,0010H        ;16 bytes to store
  223.         mov     ax,0040H
  224.         mov     ds,ax           ;BIOS data segment
  225.         assume  ds:nothing
  226.         mov     dx,00F0H        ;interapplications communication area
  227.         call    blockwrite      ;write interapp communications area to file
  228.         assume  ds:cseg
  229.  
  230. ;store the parent's psp
  231. parent: push    ds
  232.         mov     cx,2                    ;2 bytes to store
  233.         mov     dx,offset parpsp        ;point to parent's psp
  234.         call    blockwrite              ;write parent psp to file
  235.         assume  ds:cseg
  236.  
  237. parlen: push    ds
  238.         mov     ax,ds:[parpsp]
  239.         dec     ax
  240.         mov     ds,ax
  241.         assume  ds:nothing
  242.         mov     dx,3                    ;ds:dx -> parent's length
  243.         mov     cx,2
  244.         call    blockwrite              ;write parent psp to file
  245.         assume  ds:cseg
  246.  
  247. ;determine whether EMS is present
  248. ems:    push    bx              ;temporarily store the file handle
  249.         xor     bx,bx           ;zero the EMS handle count in case EMS not present
  250.         mov     dx,offset emsnm
  251.         mov     ax,3D00H
  252.         int     21H
  253.         jb      sthand          ;EMS driver not installed
  254.  
  255. ;EMS present, close the open "handle" first
  256.         mov     bx,ax           ;EMS handle into bx
  257.         mov     ah,3EH
  258.         int     21H             ;close handle
  259.  
  260. ;get the current EMS page map
  261.         mov     ah,4DH
  262.         mov     di,offset emsmap ;es=cs already
  263.         xor     bx,bx           ;required by some versions of EMM (bug workaround)
  264.         cld                     ;required by some versions of EMM
  265.         int     67H
  266.         or      ah,ah
  267.         jz      sthand          ;result ok
  268.         xor     bx,bx           ;error, return zero EMS handles
  269.  
  270. ;store the number of active handles
  271. sthand: mov     emscnt,bx               ;count of active handles
  272.  
  273. ;write the handle table to disk
  274.         shl     bx,1
  275.         shl     bx,1                    ;4 bytes per handle
  276.         inc     bx
  277.         inc     bx                      ;2 more bytes for the handle count
  278.         mov     cx,bx                   ;number of bytes to write
  279.         pop     bx                      ;get file handle back
  280.         mov     dx,offset emscnt        ;what we're writing
  281.         push    ds
  282.         call    blockwrite              ;write EMS table to file
  283.         assume  ds:cseg
  284.  
  285. ;write the allocated mcb chain
  286. stomcb: push    bx                      ;save file handle
  287.         mov     ah,52H                  ;get first mcb segment
  288.         int     21H
  289.         mov     ax,es:[bx-2]            ;ax=first mcb
  290.         push    cs
  291.         pop     es                      ;es=cs
  292.  
  293.         mov     di,emscnt               ;get starting address of mcbmap
  294.         shl     di,1
  295.         shl     di,1
  296.         add     di,offset emsmap
  297.         mov     si,di                   ;cs:[si] -> mcbcnt
  298.         add     di,2                    ;cs:[di] -> mcbmap
  299.         xor     cx,cx                   ;cx will count mcbs
  300.         cld
  301.         push    ds
  302.         assume  ds:nothing
  303.  
  304. mcbnext:stosw                           ;store mcb segment held by ax
  305.         mov     ds,ax                   ;ds:[0] points to mcb
  306.         mov     ax,ds:[1]               ;get mcb owner
  307.         stosw                           ;store it
  308.         inc     cx                      ;increment count
  309.         cmp     byte ptr ds:[0],'Z'     ;end of mcb chain?
  310.         je      mcbdone
  311.         mov     ax,ds                   ;restore ax to mcb segment
  312.         inc     ax                      ;skip over mcb itself
  313.         add     ax,ds:[3]               ;add length of memory block
  314.         jmp     mcbnext
  315.  
  316. mcbdone:mov     ax,cs:firsthimcb        ;check for high memory
  317.         or      ax,ax
  318.         jz      mcbend
  319.         mov     cs:firsthimcb,0         ;only do it once
  320.         jmp     mcbnext
  321.  
  322. mcbend: pop     ds
  323.         assume  ds:cseg
  324.         mov     [si],cx                 ;store number of mcbs
  325.         sub     di,si                   ;di=number of bytes in mcb group table
  326.         mov     cx,di                   ;count of bytes in cx
  327.         mov     dx,si                   ;what we're writing (mcbcnt+mcbmap)
  328.         pop     bx                      ;get file handle back
  329.         push    ds
  330.         call    blockwrite              ;write mcb table to file
  331.         assume  ds:cseg
  332.  
  333. ;close up the table file
  334. closfl: mov     ah,3EH
  335.         int     21H                     ;close handle
  336.         jae     idstr                   ;ok, continue
  337.  
  338.         mov     dx,offset badcls        ;error while closing file
  339.         jmp     delfil
  340.  
  341. ;put a standard ID string into the PSP for RELEASE to check
  342. idstr:  mov     si,offset id
  343.         mov     di,60H                  ;unused area of the PSP
  344.         mov     cx,idlen                ;characters in ID string
  345.         cld
  346.         rep     movsb                   ;copy string
  347.  
  348. ;copy the filename into the command tail
  349.         mov     si,offset filnm
  350.         mov     di,offset cmdlin
  351.         xor     cx,cx
  352. nxtf:   lodsb
  353.         or      al,al
  354.         jz      donf
  355.         inc     cx
  356.         stosb
  357.         jmp     nxtf
  358. donf:   mov     cmdlen,cl
  359.  
  360. ;print message and TSR
  361. gores:  cmp     quiet,0         ;check quiet flag
  362.         jnz     gores1
  363.         mov     dx,offset didit
  364.         mov     ah,9
  365.         int     21H             ;write success message including filename
  366.         mov     dx,offset crlf  ;newline
  367.         mov     ah,9
  368.         int     21H
  369.  
  370. gores1: xor     dx,dx           ;get number of paragraphs to keep
  371.         mov     dl,cmdlen       ;length of command line
  372.         add     dx,0090H        ;rest of PSP plus paragraph margin
  373.         mov     cl,4
  374.         shr     dx,cl           ;convert to paragraphs
  375.         mov     ax,3100H
  376.         int     21H             ;terminate but stay resident
  377.  
  378. ;close mark file, delete it, show error message
  379. errclo: mov     ah,3EH
  380.         int     21H                     ;close handle, ignore error
  381.  
  382. ;delete mark file and show error message
  383.         assume  ds:cseg
  384. delfil: push    dx
  385.         mov     dx,offset filnm
  386.         mov     ah,41H
  387.         int     21H
  388.         pop     dx
  389.  
  390. ;error output - show syntax line
  391. ;dx has offset of error message
  392. errmsg: mov     ah,9
  393.         int     21H
  394. error:
  395.         mov     dx,offset syntax
  396.         mov     ah,9
  397.         int     21H
  398.         mov     ax,4C01H
  399.         int     21H
  400.  
  401. fmark   endp
  402.  
  403. ;blockwrite assumes that ds was pushed before the call
  404. blockwrite proc near
  405.         mov     ah,40H
  406.         int     21H             ;write block to file
  407.         pop     dx              ;get return address
  408.         pop     ds              ;get ds back
  409.         assume  ds:cseg
  410.         push    dx              ;return address back on stack
  411.         mov     dx,offset nowrit
  412.         jc      errclo          ;jump if error during write
  413.         cmp     ax,cx
  414.         jne     errclo          ;jump if not all bytes written
  415.         ret
  416. blockwrite endp
  417.  
  418. upcase  proc    near
  419.         cmp     al,'a'
  420.         jb      noup
  421.         cmp     al,'z'
  422.         ja      noup
  423.         and     al,0DFH          ;uppercase
  424. noup:   ret
  425. upcase  endp
  426.  
  427. findhidos proc near
  428. ;returns ax = first high mcb, or 0 if none found
  429.         mov     ah,52H                  ;get first mcb segment
  430.         int     21H
  431.         mov     ax,es:[bx-2]            ;ax=first mcb
  432.  
  433.         push    ds
  434.         assume  ds:nothing
  435.  
  436. @@1:    cmp     ax,9FFFH                ;above 640K?
  437.         ja      @@2                     ;jump if so
  438.         mov     ds,ax                   ;ds:[0] points to mcb
  439.         xor     ax,ax                   ;set ax to zero in case we exit here
  440.         cmp     byte ptr ds:[0],'Z'     ;end of mcb chain?
  441.         je      @@2                     ;exit if so
  442.         mov     ax,ds                   ;restore ax to mcb segment
  443.         inc     ax                      ;skip over mcb itself
  444.         add     ax,ds:[3]               ;add length of memory block
  445.         jmp     @@1
  446.  
  447. @@2:    pop     ds                      ;ds = cs
  448.         assume  ds:cseg
  449.         ret
  450. findhidos endp
  451.  
  452. emsnm   db      'EMMXXXX0',0    ;file name for testing EMS presence
  453. id      db      'FM3.5 TSR'     ;id string for RELEASE check
  454. idlen   equ     $-id
  455.  
  456. ;messages
  457. badfil  db      13,10,'Could not open file for writing',36
  458. nowrit  db      13,10,'Error while writing',36
  459. badcls  db      13,10,'Error closing table file',36
  460. badopt  db      13,10,'Bad command line option',36
  461. syntax  db      13,10,'Syntax:  FMARK [/Q] [d:][path]filename'
  462. crlf    db      13,10,36
  463. didit   db      'FMARK 3.5, Copyright 1993 TurboPower Software',13,10
  464. didit2  db      'Marked current memory position in '
  465.  
  466. ;data storage area
  467. filnm   db      50H dup (36)    ;mark file name
  468. quiet   db      0               ;quiet flag
  469. xmsadr  label   dword           ;XMS control address
  470. xmsxxx  dw      2 dup (0)
  471. firsthimcb dw   0               ;segment of first mcb in high mem
  472. emscnt  dw      0               ;holds number of active pages in map that follows
  473. emsmap  =       $               ;EMS page map (up to 1024 bytes)
  474. mcbcnt  =       emsmap+400H     ;number of allocated mcbs
  475. mcbmap  =       mcbcnt+2        ;MCB map (up to 1024 bytes)
  476.  
  477. Cseg    ends
  478.         end    Fmark
  479.